Introduction to the Axis2 Module

The J2XB Axis2 module allows to create Axis2 Web Services with auto-generated WSDL from the service class using the J2XB annotations. The module uses the WS-RPC style, where each service method is mapped as a web service operation, the method parameters are mapped as the method input message, the method result as the output message and exceptions as fault messages.

The J2XB Axis2 module is unique in that it brings the flexability and power of J2XB XML schema generation into Axis2, allowing high quality WSDL generation which includes things like constraints (or XML Facets), substitution groups and advanced type mappings.

Note that the J2XB Axis2 module requires J2XB version 1.1+

Creating a J2XB Web Service

To create a J2XB Axis2 Web Service one needs only to create a POJO class (or interface) to be exposed as the Web Service. The parameters, return types and exceptions used by this class can then be mapped using J2XB. The service is deployed as a standard Axis2 service as an aar archive (without WSDL document in the aar ) with indication of the J2XB module in the services.xml file.

The following example is the standard Axis2 Stock Quote service adapted to use the J2XB Axis2 module.

Service Implementation class

The service implementation class is the same one used in the Axis2 examples, with the exception of some J2XB annotations.

package samples.quickstart.service.com;

public class StockQuoteService {
  private HashMap<String, Double> map = new HashMap<String, Double>();


  @MOValidationNumber(minInclusive = "0")
  public double getPrice(
      @MOValidationString(minLength = 2, maxLength = 7, patterns = ("[A-Z0-9\\.]+"))
      String symbol) {

    Double price = map.get(symbol);
    if(price != null){
      return price;
    }
    return 42.00;
  }

  public void update(
      @MOValidationString(minLength = 2, maxLength = 7, patterns = ("[A-Z0-9\\.]+"))
      String symbol,
      @MOValidationNumber(minInclusive = "0")
      double price) {

    map.put(symbol, price);
  }
}

Using the J2XB annotations we have added constraints (Facets) to ensure proper usage of the service. A Stock symbol is restricted to be between 2 to 7 uppercase characters or a dot. A Stock price is a floating point possitive number, which can be 0.

Deploying the Service

In order to deploy the service, we need to pack the service into a standard Axis2 aar archive. The archive struture will be

  quick-start-1.0.0.aar
  +-- META-INF
  |   +-- services.xml
  +-- samples
      +-- quickstart
          +-- service
              +-- pojo
                  +-- StockQuoteService.class

Notice that there is no explicit WSDL file in the aar archive - it is auto-generated by the J2XB module.

The only difference from a standard Axis2 service is in the services.xml file -

<service name="StockQuoteService" scope="application" targetNamespace="http://quickstart.samples/">
  <description>
    Stock Quote Service
  </description>
  <module ref="J2XB"/>
  <schema schemaNamespace="http://quickstart.samples/xsd"/>
  <parameter name="ServiceClass">samples.quickstart.service.pojo.StockQuoteService</parameter>
</service>

Notice that the services.xml file does not contain messageReceiver definitions - those are not needed as the J2XB module will replace the Message Receivers with its own Message Receivers (to marshal the parameters using J2XB).

The Generated WSDL

Below is the generated WSDL for the Stock Quote Service from above. Notice the wsdl:types section including the generated XML Schema - it includes the restrictions defined using the J2XB annotations.

<?xml version="1.0" encoding="UTF-8"?>
<wsdl:definitions xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:axis2="http://quickstart.samples/" xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/" xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/" xmlns:http="http://schemas.xmlsoap.org/wsdl/http/" xmlns:ns1="http://org.apache.axis2/xsd" xmlns:wsaw="http://www.w3.org/2006/05/addressing/wsdl" xmlns:ns="http://quickstart.samples/xsd" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" targetNamespace="http://quickstart.samples/">
  <wsdl:documentation>StockQuoteService</wsdl:documentation>
  <wsdl:types>
    <xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" targetNamespace="http://quickstart.samples/xsd">
      <xs:element name="getPrice">
        <xs:complexType>
          <xs:sequence>
            <xs:element name="symbol">
              <xs:simpleType>
                <xs:restriction base="xs:string">
                  <xs:minLength value="2"/>
                  <xs:maxLength value="7"/>
                  <xs:pattern value="[\p{Upper}\.]+"/>
                </xs:restriction>
              </xs:simpleType>
            </xs:element>
          </xs:sequence>
        </xs:complexType>
      </xs:element>
      <xs:element name="getPriceResponse">
        <xs:complexType>
          <xs:sequence>
            <xs:element name="return">
              <xs:simpleType>
                <xs:restriction base="xs:double">
                  <xs:minInclusive value="0"/>
                </xs:restriction>
              </xs:simpleType>
            </xs:element>
          </xs:sequence>
        </xs:complexType>
      </xs:element>
      <xs:element name="update">
        <xs:complexType>
          <xs:sequence>
            <xs:element name="symbol">
              <xs:simpleType>
                <xs:restriction base="xs:string">
                  <xs:minLength value="2"/>
                  <xs:maxLength value="7"/>
                  <xs:pattern value="[\p{Upper}\.]+"/>
                </xs:restriction>
              </xs:simpleType>
            </xs:element>
            <xs:element name="price">
              <xs:simpleType>
                <xs:restriction base="xs:double">
                  <xs:minInclusive value="0"/>
                </xs:restriction>
              </xs:simpleType>
            </xs:element>
          </xs:sequence>
        </xs:complexType>
      </xs:element>
    </xs:schema>
  </wsdl:types>
  <wsdl:message name="getPriceRequest">
    <wsdl:part name="parameters" element="ns:getPrice"/>
  </wsdl:message>
  <wsdl:message name="getPriceResponse">
    <wsdl:part name="parameters" element="ns:getPriceResponse"/>
  </wsdl:message>
  <wsdl:message name="updateRequest">
    <wsdl:part name="parameters" element="ns:update"/>
  </wsdl:message>
  <wsdl:portType name="StockQuoteServicePortType">
    <wsdl:operation name="getPrice">
      <wsdl:input message="axis2:getPriceRequest" wsaw:Action="urn:getPrice"/>
      <wsdl:output message="axis2:getPriceResponse" wsaw:Action="urn:getPriceResponse"/>
    </wsdl:operation>
    <wsdl:operation name="update">
      <wsdl:input message="axis2:updateRequest" wsaw:Action="urn:update"/>
    </wsdl:operation>
  </wsdl:portType>
  <wsdl:binding name="StockQuoteServiceSoap11Binding" type="axis2:StockQuoteServicePortType">
    <soap:binding transport="http://schemas.xmlsoap.org/soap/http" style="document"/>
    <wsdl:operation name="getPrice">
      <soap:operation soapAction="urn:getPrice" style="document"/>
      <wsdl:input>
        <soap:body use="literal"/>
      </wsdl:input>
      <wsdl:output>
        <soap:body use="literal"/>
      </wsdl:output>
    </wsdl:operation>
    <wsdl:operation name="update">
      <soap:operation soapAction="urn:update" style="document"/>
      <wsdl:input>
        <soap:body use="literal"/>
      </wsdl:input>
    </wsdl:operation>
  </wsdl:binding>
  <wsdl:binding name="StockQuoteServiceSoap12Binding" type="axis2:StockQuoteServicePortType">
    <soap12:binding transport="http://schemas.xmlsoap.org/soap/http" style="document"/>
    <wsdl:operation name="getPrice">
      <soap12:operation soapAction="urn:getPrice" style="document"/>
      <wsdl:input>
        <soap12:body use="literal"/>
      </wsdl:input>
      <wsdl:output>
        <soap12:body use="literal"/>
      </wsdl:output>
    </wsdl:operation>
    <wsdl:operation name="update">
      <soap12:operation soapAction="urn:update" style="document"/>
      <wsdl:input>
        <soap12:body use="literal"/>
      </wsdl:input>
    </wsdl:operation>
  </wsdl:binding>
  <wsdl:binding name="StockQuoteServiceHttpBinding" type="axis2:StockQuoteServicePortType">
    <http:binding verb="POST"/>
    <wsdl:operation name="getPrice">
      <http:operation location="StockQuoteService/getPrice"/>
      <wsdl:input>
        <mime:content type="text/xml" part="getPrice"/>
      </wsdl:input>
      <wsdl:output>
        <mime:content type="text/xml" part="getPrice"/>
      </wsdl:output>
    </wsdl:operation>
    <wsdl:operation name="update">
      <http:operation location="StockQuoteService/update"/>
      <wsdl:input>
        <mime:content type="text/xml" part="update"/>
      </wsdl:input>
    </wsdl:operation>
  </wsdl:binding>
  <wsdl:service name="StockQuoteService">
    <wsdl:port name="StockQuoteServiceHttpSoap11Endpoint" binding="axis2:StockQuoteServiceSoap11Binding">
      <soap:address location="http://10.234.10.148:8080/axis2/services/StockQuoteService.StockQuoteServiceHttpSoap11Endpoint"/>
    </wsdl:port>
    <wsdl:port name="StockQuoteServiceHttpSoap12Endpoint" binding="axis2:StockQuoteServiceSoap12Binding">
      <soap12:address location="http://10.234.10.148:8080/axis2/services/StockQuoteService.StockQuoteServiceHttpSoap12Endpoint"/>
    </wsdl:port>
    <wsdl:port name="StockQuoteServiceHttpEndpoint" binding="axis2:StockQuoteServiceHttpBinding">
      <http:address location="http://10.234.10.148:8080/axis2/services/StockQuoteService.StockQuoteServiceHttpEndpoint"/>
    </wsdl:port>
  </wsdl:service>
</wsdl:definitions>